package appli;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.TreeSet;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/**
 * Permet d'avoir une interface graphique (comme d'ecrit dans le mode d'emploi).
 * Impleente en Java Swing. Permet une interface avec l'utilisateur et un
 * affichage des reultats.
 * 
 */
public class Interface extends JFrame implements ActionListener {

	private static final long serialVersionUID = 1L;
	private Application application;
	private String typeIndex;
	private String typeModel;
	private boolean removeStopWords;

	private JMenuBar jmb;
	private JMenu jmFile;
	private JMenu jmMode;
	private JMenu jmAbout;
	private JMenuItem jmiFile1;
	private JMenuItem jmiFile2;
	private JMenuItem jmiMode1;
	private JMenuItem jmiAbout1;
	private JMenuItem jmiAbout2;

	private JLabel logo;
	private JPanel entreePanel;
	private JPanel resultPanel;
	private JScrollPane listePane;

	private JTextField entreeField;
	private JTextArea resultField;

	private JButton entreeValid;
	private JButton returnValid;

	/**
	 * Constructeur de l'interfacage.
	 */
	public Interface(Application app) {
		super();
		this.setTitle("PPS Moteur de recherche");
		this.setPreferredSize(new Dimension(600, 400));
		this.setLayout(new BorderLayout());
		this.setLocation(300, 50);
		this.setResizable(false);
		this.application = app;
		this.typeIndex = null;
		this.typeModel = null;
		this.removeStopWords = false;

		/* Initialisation de menu */
		jmb = new JMenuBar();
		this.add(jmb, BorderLayout.NORTH);
		jmFile = new JMenu("File");
		jmMode = new JMenu("Mode");
		jmAbout = new JMenu("About");

		jmb.add(jmFile);
		jmb.add(jmMode);
		jmb.add(jmAbout);
		jmiFile1 = new JMenuItem("Start");
		jmiFile2 = new JMenuItem("Exit");
		jmiMode1 = new JMenuItem("Set Searching Mode");
		jmiAbout1 = new JMenuItem("Help");
		jmiAbout2 = new JMenuItem("Credit");
		jmFile.add(jmiFile1);
		jmFile.add(jmiFile2);
		jmMode.add(jmiMode1);
		jmAbout.add(jmiAbout1);
		jmAbout.add(jmiAbout2);

		jmiFile1.addActionListener(this);
		jmiFile1.setActionCommand("start");
		jmiFile2.addActionListener(this);
		jmiFile2.setActionCommand("exit");
		jmiMode1.addActionListener(this);
		jmiMode1.setActionCommand("mode");
		jmiAbout1.addActionListener(this);
		jmiAbout1.setActionCommand("help");
		jmiAbout2.addActionListener(this);
		jmiAbout2.setActionCommand("credit");

		/* Initialisation des panels */
		entreePanel = new JPanel();
		resultPanel = new JPanel();
		listePane = new JScrollPane();

		this.add(entreePanel, BorderLayout.CENTER);

		entreePanel.setLayout(new FlowLayout());
		this.entreePanel.setBackground(Color.WHITE);

		/* Initialisation des labels */
		logo = new JLabel(new ImageIcon("Logo_moteur2.jpg"));
		entreePanel.add(logo);

		/* Initialisation des textFields */
		entreeField = new JTextField();
		entreeField.setPreferredSize(new Dimension(550, 24));

		entreePanel.add(entreeField);

		/* Initialisation des buttons */
		entreeValid = new JButton("Let's go");
		entreeValid.addActionListener(this);
		entreeValid.setActionCommand("enter");
		entreePanel.add(entreeValid);

		returnValid = new JButton("Return");
		returnValid.addActionListener(this);
		returnValid.setActionCommand("return");

		pack();
		setVisible(true);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	/**
	 * Afficher les resultats dans un JList
	 * 
	 * @param result
	 */
	public void showResult(HashMap<String, Float> result) {
		this.remove(this.entreePanel);
		this.entreePanel = null;
		this.entreeField.setText(null);

		resultField = new JTextArea();
		resultField.setFont(new Font("monospaced", Font.BOLD, 14));
		resultField.setEditable(false);

		// creer un map pour ordonner le resultat
		final HashMap<String, Float> scores = new HashMap<String, Float>();
		for (String s : result.keySet()) {
			scores.put(s, result.get(s));
		}

		/** ajouter les texts **/
		this.resultField.append("The result for <"
				+ this.application.getRequete() + "> are listed below:\n\n");
		// ordonner le resultat
		TreeSet<String> files = new TreeSet<String>(new Comparator<String>() {

			@Override
			public int compare(String o1, String o2) {
				// on veut classer dans l'ordre DESCENDANT
				// (donc ordre inverse)
				if (scores.get(o1) >= scores.get(o2)) {
					return -1;
				} else {
					return 1;
				}
			}

		});
		files.addAll(scores.keySet());

		// Afficher le resultat
		if (files.size() == 0) {
			this.resultField
					.append("Sorry, but we can't find any document for your request.\n");
		} else {
			for (String s : files) {
				this.resultField.append(s + "\t" + scores.get(s) + "\n");
			}
		}

		// Afficher le suggestion de correction d'erreur
		if (this.application.getModele().getSuggestionRequete() != null) {
			ArrayList<String> suggest = this.application.getModele()
					.getSuggestionRequete();
			if (suggest.size() != 0) {
				if (this.application.getModele().isSuggestionActif()) {
					this.resultField.append("\nYou can try " + suggest
							+ " to get more results!");
				}
			}
		}

		/* Affichier le resultat sur console */
		System.out.println("\nThe request is -> "
				+ this.application.getRequete());
		System.out.println("Index trie : This is the result of your search...");
		int nb = 1;
		for (String s : files) {
			System.out.println(nb + " -> " + s + "\t" + scores.get(s));
			nb++;
		}

		this.resultPanel = new JPanel();
		this.listePane = new JScrollPane(resultField);
		resultPanel.setPreferredSize(new Dimension(550, 300));
		listePane.setPreferredSize(new Dimension(550, 300));
		this.add(resultPanel, BorderLayout.CENTER);

		resultPanel.add(listePane);
		resultPanel.add(returnValid);

		setVisible(true);
	}

	/**
	 * Retourner vers la page d'acceuil, supprimer le resultat obtient
	 * precedant.
	 */
	public void returnToRequest() {
		this.remove(this.resultPanel);
		this.resultPanel = null;
		this.resultField = null;

		this.application.setRequete(null);
		this.application.setResult(null);
		this.application.getModele().reinitialiser();

		this.entreePanel = new JPanel();
		this.entreePanel.setBackground(Color.WHITE);
		entreePanel.add(logo);
		entreePanel.add(entreeField);
		entreePanel.add(entreeValid);
		this.add(entreePanel, BorderLayout.CENTER);

		pack();
		setVisible(true);
	}

	@Override
	public void actionPerformed(ActionEvent arg0) {

		/******************** POUR LES MENUS **********************/
		// Recommencer le programme sans fermer la fenetre
		if (arg0.getActionCommand().compareTo("start") == 0) {
			System.out.println("Start");
			if (this.entreePanel != null) {
				this.entreeField.setText(null);
			} else {
				this.returnToRequest();
			}

			this.typeIndex = null;
			this.typeModel = null;

		}

		// Fermer le programme
		else if (arg0.getActionCommand().compareTo("exit") == 0) {
			System.out.println("Exit");
			System.exit(0);
		}

		// Choisir le type d'index (avec/sans stemming; modele boolean/normal)
		else if (arg0.getActionCommand().compareTo("mode") == 0) {
			System.out.println("Mode");
			ModeleConfig mc = new ModeleConfig(this);
		}

		else if (arg0.getActionCommand().compareTo("help") == 0) {
			System.out.println("Help");
			JOptionPane
					.showMessageDialog(
							this,
							"To begin a research, \n"
									+ "you must choose a index mode (2 choices to make)\n"
									+ "and choose a search mode (2 choices to make)\n"
									+ "then a simple click will get you to the right article you want!\n\n",
							"Help", JOptionPane.INFORMATION_MESSAGE);
		}

		else if (arg0.getActionCommand().compareTo("credit") == 0) {
			System.out.println("Credit");
			JOptionPane
					.showMessageDialog(
							this,
							"PPS Moteur: a super research engine \n"
									+ "designed by Weiya CHEN, Alienor LATOUR and Nathanael MASRI \n"
									+ "for EIT projet of Polytech Paris-Sud\n\n",
							"Credit", JOptionPane.INFORMATION_MESSAGE);
		}

		/******************** POUR LES BUTTONS **********************/
		// Lancer le recherche
		else if (arg0.getActionCommand().compareTo("enter") == 0
				&& !entreeField.getText().isEmpty()) {
			System.out.println("Enter");
			if (typeIndex == null || typeModel == null) {
				JOptionPane
						.showMessageDialog(
								this,
								"Please choose an Index and Model type before the search for information!",
								"Attention", JOptionPane.WARNING_MESSAGE);
			} else {

				this.application.setRequete(this.entreeField.getText());

				this.application.searchInfo();

				this.showResult(this.application.getResult());
			}

		}

		// Retourner et recommencer un recherche
		else if (arg0.getActionCommand().compareTo("return") == 0) {
			System.out.println("Return");
			this.returnToRequest();
		}
	}

	public Application getApplication() {
		return application;
	}

	public void setApplication(Application application) {
		this.application = application;
	}

	public String getTypeIndex() {
		return typeIndex;
	}

	public void setTypeIndex(String typeIndex) {
		this.typeIndex = typeIndex;
	}

	public String getTypeModel() {
		return typeModel;
	}

	public void setTypeModel(String typeModel) {
		this.typeModel = typeModel;
	}

	public boolean isRemoveEmptyWords() {
		return removeStopWords;

	}

	public void setRemoveEmptyWords(boolean removeStopWords) {
		this.removeStopWords = removeStopWords;

	}

}
